/**
 * @param {string} path
 * @returns {Boolean}
 */
export function isExternal(path) {
  return /^(https?:|mailto:|tel:)/.test(path);
}

/**
 * 判断值是否为空，支持空字符串，null，undefined，Object，String，Number，Date
 * @param {*} value 验证的值
 * @returns 返回true和false
 */
export const isNull = (value) => {
  return (
    value == undefined ||
    value == null ||
    value == "" ||
    (isObject(value) && Object.keys(value).length == 0) ||
    value.length == 0
  );
}

/**
 * 判断是否是整数Integer
 * @param {*} value 参数
 * @returns 返回true和false
 */
export const isInteger = (value) => {
  return Number.isInteger(value);
}

/**
 * 判断是否是数字Number
 * @param {*} value 参数
 * @returns 返回true和false
 */
export const isNumber = (value) => {
  return Object.prototype.toString.call(value).slice(8, -1) === "Number";
}

/**
 * 判断是否是Date
 * @param {*} value 参数
 * @returns 返回true和false
 */
export const isDate = (value) => {
  return Object.prototype.toString.call(value).slice(8, -1) === "Date";
}

/**
 * 判断是否是Object
 * @param {*} value 参数
 * @returns 返回true和false
 */
export const isObject = (value) => {
  return Object.prototype.toString.call(value).slice(8, -1) === "Object";
}

/**
 * 判断是否是Array
 * @param {*} value 参数
 * @returns 返回true和false
 */
export const isArray = (value) => {
  return Object.prototype.toString.call(value).slice(8, -1) === "Array";
}

/**
 * 判断是否是String
 * @param {*} value 参数
 * @returns 返回true和false
 */
export const isString = (value) => {
  return Object.prototype.toString.call(value).slice(8, -1) === "String";
}

/**
 * 判断是否是Boolean
 * @param {*} value 参数
 * @returns 返回true和false
 */
export const isBoolean = (value) => {
  return Object.prototype.toString.call(value).slice(8, -1) === "Boolean";
}

/**
 * 判断是否是Function
 * @param {*} value 参数
 * @returns 返回true和false
 */
export const isFunction = (value) => {
  return Object.prototype.toString.call(value).slice(8, -1) === "Function";
}

/**
 * 判断是否是正确url
 * @param {string} url
 * @returns {Boolean}
 */
export function isURL(url) {
  const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/;
  return reg.test(url);
}

/**
 * 判断是否全是小写
 * @param {string} str
 * @returns {Boolean}
 */
export function isLowerCase(str) {
  const reg = /^[a-z]+$/;
  return reg.test(str);
}

/**
 * 判断是否全是大写
 * @param {string} str
 * @returns {Boolean}
 */
export function isUpperCase(str) {
  const reg = /^[A-Z]+$/;
  return reg.test(str);
}

/**
 * 判断字符串是否全是中文
 * @param {String} value 参数
 * @returns 返回true和false
 */
export const isChinese = (value) => {
  return /^[\u4E00-\u9FA5]+$/.test(value);
}

/**
 * 判断是否全是英文
 * @param {string} str
 * @returns {Boolean}
 */
export function isAlphabets(str) {
  const reg = /^[A-Za-z]+$/;
  return reg.test(str);
}

/**
 * 判断是否是正确的email
 * @param {string} email
 * @returns {Boolean}
 */
export function isEmail(email) {
  const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
  return reg.test(email);
}

/**
 * 判断是否是正确的手机号
 * @param {string} phone
 * @returns {Boolean}
 */
export function isPhone(phone) {
  const reg = /^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[189]))\d{8}$/;
  return reg.test(phone);
}

/**
 * 判断是否是正确的邮政编码
 * @param {string} str
 * @returns {Boolean}
 */
export function isPostCode(str) {
  const reg = /^[1-9]\d{5}(?!\d)$/g;
  return reg.test(str);
}

/**
 * 判断是否是正确的固定座机号, 座机/固定电话 "XXXX-XXXXXXX"
 * @param {string} tel
 * @returns {Boolean}
 */
export function isTel(tel) {
  // const reg = /(^(0[0-9]{2,3}\-)?([2-9][0-9]{6,7})+(\-[0-9]{1,4})?$)|(^((\(\d{3}\))|(\d{3}\-))?(1[3578]\d{9})$)|(^(400)-(\d{3})-(\d{4})(.)(\d{1,4})$)|(^(400)-(\d{3})-(\d{4}$))/;
  const reg = /(^(\d{2,4}[-]?)?\d{3,8}([-]?\d{3,8})?([-]?\d{1,7})?$)|(^0?1[35]\d{9}$)/
  return reg.test(tel);
}

/**
 * 判断是否是正确的身份证
 * @param {string} idcard
 * @returns {Boolean}
 */
export function isIdCard(idcard) {
  const reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
  // let reg = /^[1-9]\d{5}(18|19|20|(3\d))\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
  return reg.test(idcard);
}

/**
 * 判断是否是正确的统一社会信用代码 18和15位
 * @param {string} uscc
 * @returns {Boolean}
 */
export function isUSCC(uscc) {
  const reg = /^([0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}|[1-9]\d{14})$/;
  return reg.test(uscc);
}


/**
 * 是否正确车牌号
 */
export const carNo = (value) => {
  // 新能源车牌
  const xreg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/
  // 旧车牌
  const creg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/
  if (value.length === 7) {
    return creg.test(value)
  } else if (value.length === 8) {
    return xreg.test(value)
  } else return false
}

/** --------------------------------------表单校验规则------------------------------------------------------------------------------  */

//校验银行卡号，银行卡校验规则(Luhn算法)
export const validBankNo = (rule, value, callback) => {
  if (value === '') {
    if (rule.required) callback('请输入银行卡号');
    else callback()
  } else {
    var wei = [],
      sumOdd = 0,
      sumEven = 0,
      length = value.length;
    for (var j = 0; j < length; j++) {
      wei[j] = parseInt(value.substring(length - j - 1, length - j)); // 从最末一位开始提取，每一位上的数值
    }
    for (var i = 0; i < length / 2; i++) {
      sumOdd += wei[2 * i];
      if (wei[2 * i + 1] * 2 > 9) wei[2 * i + 1] = wei[2 * i + 1] * 2 - 9;
      else wei[2 * i + 1] *= 2;
      sumEven += wei[2 * i + 1];
    }
    if (!(sumOdd + sumEven) % 10 == 0) {
      callback('请输入正确的银行卡号');
    } else {
      callback();
    }
  }
}

// 手机号
export const validPhone = (rule, value, callback) => {
  if (value === '') {
    if (rule.required) callback('请输入手机号');
    else callback()
  } else {
    if (!isPhone(value) && value != '') {
      callback('请输入正确的手机号码');
    } else {
      callback();
    }
  }
}

// 固定电话
export const validTel = (rule, value, callback) => {
  if (value === '') {
    if (rule.required) callback('请输入固定电话号码');
    else callback()
  } else {
    if (!isTel(value) && value != '') {
      callback('请输入正确的固定电话号码');
    } else {
      callback();
    }
  }
}

// 邮箱
export const validEmail = (rule, value, callback) => {
  if (value === '') {
    if (rule.required) callback('请输入邮箱地址');
    else callback()
  } else {
    if (!isEmail(value) && value != '') {
      callback('请输入正确的邮箱');
    } else {
      callback();
    }
  }
}

// 邮政编码
export const validPostcode = (rule, value, callback) => {
  if (value === '') {
    if (rule.required) callback('请输入邮政编码');
    else callback()
  } else {
    if (!isPostCode(value) && value != '') {
      callback('请输入正确的邮政编码');
    } else {
      callback();
    }
  }
};

// 身份证
export const validIdCard = (rule, value, callback) => {
  if (value === '') {
    if (rule.required) callback('请输入身份证号');
    else callback()
  } else {
    if (!isIdCard(value) && value != '') {
      callback('请输入正确的身份证号码');
    } else {
      callback();
    }
  }
}

// 统一社会信用代码
export const validUSCC = (rule, value, callback) => {
  if (value === '') {
    if (rule.required) callback('请输入统一社会信用代码');
    else callback()
  } else {
    if (!isUSCC(value) && value != '') {
      callback('请输入正确的统一社会信用代码');
    } else {
      callback();
    }
  }
}

// 统一社会信用代码或身份证
export const validUsccId = (rule, value, callback) => {
  if (!value) {
    if (rule.required) callback('请输入统一社会信用代码或身份证号');
    else callback()
  } else {
    if (isUSCC(value) || isIdCard(value)) {
      callback();
    } else {
      callback('请输入正确的统一社会信用代码或身份证号');
    }
  }
}

// 账号校验
export const validCode = (rule, value, callback) => {
  if (!value) {
    if (rule.required) callback('请输入账号');
    else callback()
  } else {
    if (!/^(?![0-9]*$)(?![a-zA-Z]*$)[a-zA-Z0-9]{6,20}$/.test(value)) {
      callback('账号必须为6-20位字母和数字组合')
    } else {
      callback()
    }
  }
}

// 验证是否包含英文数字以及下划线
export const validPassword = (rule, value, callback) => {
  const reg = /^[_a-zA-Z0-9]+$/;
  if (value == '' || value == undefined || value == null) {
    if (rule.required) callback('请输入');
    else callback()
  } else {
    if (!reg.test(value)) {
      callback('仅由英文字母，数字以及下划线组成');
    } else {
      callback();
    }
  }
}

// 中文校验
export const validChinese = (rule, value, callback) => {
  if (value === '') {
    if (rule.required) callback('不能为空');
    else callback()
  } else {
    if (!isChinese(value)) {
      callback('不可输入特殊字符')
    } else {
      callback()
    }
  }
}

// 纯数字校验
export const validNumber = (rule, value, callback) => {
  if (value === '') {
    if (rule.required) callback('请输入值');
    else callback()
  } else {
    if (!isNumber(value)) {
      callback('请输入数字')
    } else {
      callback()
    }
  }
}

//正整数
export const validPositiveInteger = (rule, value, callback) => {
  if (value === '') {
    if (rule.required) callback('请输入值');
    else callback()
  } else {
    const reg = /^[1-9][0-9]*$/;
    if ((!reg.test(value)) && value != '') {
      callback('必须是正整数！');
    } else {
      callback();
    }
  }
}

// 合法IP
export const validIp = (rule, value, callback) => {
  if (value === '') {
    if (rule.required) callback('请输入ip地址');
    else callback()
  } else {
    const reg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;
    if ((!reg.test(value)) && value != '') {
      callback('请输入正确的IP地址');
    } else {
      callback();
    }
  }
}

// 验证端口是否在[0,65535]之间
export const validPort = (rule, value, callback) => {
  if (value === '') {
    if (rule.required) callback('输入不可以为空');
    else callback()
  }
  setTimeout(() => {
    if (value == '' || typeof (value) == undefined) {
      callback('请输入端口值');
    } else {
      const re = /^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/;
      const rsCheck = re.test(value);
      if (!rsCheck) {
        callback('请输入在[0-65535]之间的端口值');
      } else {
        callback();
      }
    }
  }, 100);
}
